package org.rcgwt.client.ui.themes;

import java.util.HashMap;
import java.util.Map;

import org.rcgwt.client.theme.CssStyle;
import org.rcgwt.client.ui.calendar.renderer.ICalendarGridRenderer;
import org.rcgwt.client.ui.calendar.renderer.ICalendarWeeksRenderer;
import org.rcgwt.client.ui.calendar.renderer.IFooterRenderer;
import org.rcgwt.client.ui.calendar.renderer.IHeaderRenderer;
import org.rcgwt.client.ui.calendar.renderer.IRenderer;
import org.rcgwt.client.ui.calendar.renderer.impl.CalendarDatesRenderer;
import org.rcgwt.client.ui.calendar.renderer.impl.CalendarFooterRenderer;
import org.rcgwt.client.ui.calendar.renderer.impl.CalendarWeekColumnRenderer;
import org.rcgwt.client.ui.calendar.renderer.impl.FullCalendarHeaderRenderer;
import org.rcgwt.client.ui.calendar.renderer.impl.MediumCalendarHeaderRenderer;
import org.rcgwt.client.ui.calendar.renderer.impl.PopupCalendarHeaderRenderer;
import org.rcgwt.client.ui.calendar.renderer.impl.ShortCalendarHeaderRenderer;
import org.rcgwt.client.ui.calendar.renderer.impl.SingleLineCalendarHeaderRenderer;

public class StandardTheme implements ITheme {

	/* Renderer Level (For rendering) */
	public enum RendererLevel {
		SIMPLE, POPUP, SHORT, MEDIUM, FULL
	}

	/* Renderer Types (For rendering) */
	public enum RendererType {
		HEADER, DATES, WEEK, FOOTER
	}

	/* Style Names */
	private static final String _CALENDAR_STYLE_CLASS = "rcgwt-richCalendar";

	private static final String _CALENDAR_POPUP_PANEL_STYLE_CLASS = "popupPanel";
	private static final String _CALENDAR_POPUP_YEAR_GRID_STYLE_CLASS = _CALENDAR_POPUP_PANEL_STYLE_CLASS
			+ "-" + "yearGrid";
	private static final String _CALENDAR_POPUP_MONTH_GRID_STYLE_CLASS = _CALENDAR_POPUP_PANEL_STYLE_CLASS
			+ "-" + "monthGrid";

	private static final String _CALENDAR_GRID_STYLE_CLASS = "grid";
	private static final String _CALENDAR_WEEK_GRID_STYLE_CLASS = "weekgrid";
	private static final String _CALENDAR_GRID_CELL_STYLE_CLASS = "gridCell";

	private static final String _CALENDAR_GRID_CELL_WEEKS_STYLE_CLASS = "weeks";
	private static final String _CALENDAR_GRID_CELL_BRIEF_DAYS_STYLE_CLASS = "briefDays";
	private static final String _CALENDAR_GRID_CELL_CURRENT_DAY_STYLE_CLASS = "currentDay";
	private static final String _CALENDAR_GRID_CELL_PREVIOUS_DAYS_STYLE_CLASS = "previousDays";

	private static final String _CALENDAR_GRID_CELL_SPECIAL_DAY_STYLE_CLASS = "specialDay";
	private static final String _CALENDAR_GRID_CELL_BUSY_DAY_STYLE_CLASS = "busyDay";
	private static final String _CALENDAR_GRID_CELL_HOLIDAYS_STYLE_CLASS = "holidays";
	private static final String _CALENDAR_GRID_CELL_OTHERS_STYLE_CLASS = "others";

	private static final String _CALENDAR_YEAR_AND_MONTH_PANEL_STYLE_CLASS = "yearAndMonthPanel";
	private static final String _CALENDAR_MEDIUM_YEAR_AND_MONTH_PANEL_STYLE_CLASS = "mediumYearAndMonthPanel";
	private static final String _CALENDAR_FULL_YEAR_PANEL_STYLE_CLASS = "fullYearPanel";
	private static final String _CALENDAR_FULL_MONTH_PANEL_STYLE_CLASS = "fullMonthPanel";
	private static final String _CALENDAR_SEMANTIC_NAVIGATION_PANEL_STYLE_CLASS = "semanticNavigationPanel";

	private static final String _CALENDAR_YEAR_LABEL_STYLE_CLASS = "yearLabel";
	private static final String _CALENDAR_MONTH_LABEL_STYLE_CLASS = "monthLabel";
	private static final String _CALENDAR_SELECTED_MONTHES_LABEL_STYLE_CLASS = "selectedFullMonthLabel";
	private static final String _CALENDAR_SELECTED_YEAR_MONTH_LABEL_STYLE_CLASS = "selectedYearMonthLabel";
	private static final String _CALENDAR_MONTHES_LABEL_STYLE_CLASS = "monthesLabel";
	private static final String _CALENDAR_SHORT_HEADER_COLUMN_STYLE_CLASS = "shortColumn";
	private static final String _CALENDAR_SINGLE_LINE_HEADER_COLUMN_STYLE_CLASS = "singleLineColumn";

	private static final String _CALENDAR_TODAY_BUTTON_STYLE_CLASS = "todayButton";
	private static final String _CALENDAR_PREVIOUS_YEAR_BUTTON_STYLE_CLASS = "previousYearButton";
	private static final String _CALENDAR_NEXT_YEAR_BUTTON_STYLE_CLASS = "nextYearButton";
	private static final String _CALENDAR_PREVIOUS_MONTH_BUTTON_STYLE_CLASS = "previousMonthButton";
	private static final String _CALENDAR_NEXT_MONTH_BUTTON_STYLE_CLASS = "nextMonthButton";

	private static final String _CALENDAR_ARROW_BUTTON_STYLE_CLASS = "arrowButton";
	private static final String _CALENDAR_PREVIOUS_BUTTON_STYLE_CLASS = "previousButton";
	private static final String _CALENDAR_NEXT_BUTTON_STYLE_CLASS = "nextButton";

	private static final String _CALENDAR_SELECTED_SUFFIX = "selected";
	private static final String _CALENDAR_DISABLED_SUFFIX = "disabled";
	private static final String _CALENDAR_FORBIDDEN_SUFFIX = "forbidden";
	private static final String _CALENDAR_CURSOR_SUFFIX = "cursor";
	private static final String _CALENDAR_OPENED_SUFFIX = "opened";

	/* CSS Styles */
	private static CssStyle MAIN_STYLE;

	private static CssStyle CALENDAR_POPUP_PANEL_STYLE;
	private static CssStyle CALENDAR_POPUP_YEAR_GRID_STYLE;
	private static CssStyle CALENDAR_POPUP_MONTH_GRID_STYLE;

	private static CssStyle CALENDAR_GRID_STYLE;
	private static CssStyle CALENDAR_WEEK_GRID_STYLE;
	private static CssStyle CALENDAR_GRID_CELL_STYLE;

	private static CssStyle CALENDAR_NO_SELECTION_GRID_CELL_STYLE;
	private static CssStyle CALENDAR_SELECTED_CELL_STYLE;
	private static CssStyle CALENDAR_CURSOR_CELL_STYLE;
	private static CssStyle CALENDAR_GRID_CELL_BRIEF_DAYS_STYLE;
	private static CssStyle CALENDAR_GRID_CELL_WEEKS_STYLE;
	private static CssStyle CALENDAR_SELECTED_GRID_CELL_WEEKS_STYLE;
	private static CssStyle CALENDAR_GRID_CELL_CURRENT_DAY_STYLE;
	private static CssStyle CALENDAR_GRID_CELL_PREVIOUS_DAYS_STYLE;

	private static CssStyle CALENDAR_GRID_CELL_HOLIDAYS_STYLE;
	private static CssStyle CALENDAR_GRID_CELL_SPECIAL_DAY_STYLE;
	private static CssStyle CALENDAR_GRID_CELL_BUSY_DAY_STYLE;
	private static CssStyle CALENDAR_GRID_CELL_OTHERS_STYLE;

	private static CssStyle CALENDAR_YEAR_AND_MONTH_PANEL_STYLE;
	private static CssStyle CALENDAR_MEDIUM_YEAR_AND_MONTH_PANEL_STYLE;
	private static CssStyle CALENDAR_FULL_YEAR_PANEL_STYLE;
	private static CssStyle CALENDAR_FULL_MONTH_PANEL_STYLE;

	private static CssStyle CALENDAR_YEAR_LABEL_STYLE;
	private static CssStyle CALENDAR_MONTH_LABEL_STYLE;
	private static CssStyle CALENDAR_SELECTED_YEAR_MONTH_LABEL_STYLE;
	private static CssStyle CALENDAR_MONTHES_LABEL_STYLE;
	private static CssStyle CALENDAR_SELECTED_MONTHES_LABEL_STYLE;
	private static CssStyle CALENDAR_SHORT_HEADER_COLUMN_STYLE;
	private static CssStyle CALENDAR_SINGLE_LINE_HEADER_COLUMN_STYLE;

	private static CssStyle CALENDAR_TODAY_BUTTON_STYLE;
	private static CssStyle CALENDAR_PREVIOUS_YEAR_BUTTON_STYLE;
	private static CssStyle CALENDAR_NEXT_YEAR_BUTTON_STYLE;
	private static CssStyle CALENDAR_PREVIOUS_MONTH_BUTTON_STYLE;
	private static CssStyle CALENDAR_NEXT_MONTH_BUTTON_STYLE;
	private static CssStyle CALENDAR_ARROW_BUTTON_STYLE;

	private static CssStyle CALENDAR_SEMANTIC_NAVIGATION_PANEL_STYLE;
	private static CssStyle CALENDAR_PREVIOUS_BUTTON_STYLE;
	private static CssStyle CALENDAR_NEXT_BUTTON_STYLE;

	/* Renderer */
	private SingleLineCalendarHeaderRenderer singleLineHeaderRenderer;
	private ShortCalendarHeaderRenderer shortHeaderRenderer;
	private PopupCalendarHeaderRenderer popupHeaderRenderer;
	private MediumCalendarHeaderRenderer mediumHeaderRenderer;
	private FullCalendarHeaderRenderer fullHeaderRenderer;
	private CalendarDatesRenderer datesRenderer;
	private CalendarWeekColumnRenderer weekRenderer;
	private CalendarFooterRenderer footerRenderer;

	/* Styles */
	/* Main Styles */
	public CssStyle getMainStyle() {
		if (MAIN_STYLE == null) {
			MAIN_STYLE = CssStyle.create(_CALENDAR_STYLE_CLASS);
		}
		return MAIN_STYLE;
	}

	public CssStyle getCalendarGridStyle() {
		if (CALENDAR_GRID_STYLE == null) {
			CALENDAR_GRID_STYLE = CssStyle.create(_CALENDAR_GRID_STYLE_CLASS);
		}
		return CALENDAR_GRID_STYLE;
	}

	/* Popup Panel styles */

	@Override
	public CssStyle getPopupPanelStyle() {
		if (CALENDAR_POPUP_PANEL_STYLE == null) {
			CALENDAR_POPUP_PANEL_STYLE = CssStyle
					.create(_CALENDAR_POPUP_PANEL_STYLE_CLASS);
		}
		return CALENDAR_POPUP_PANEL_STYLE;
	}

	@Override
	public CssStyle getPopupYearGridStyle() {
		if (CALENDAR_POPUP_YEAR_GRID_STYLE == null) {
			CALENDAR_POPUP_YEAR_GRID_STYLE = CssStyle
					.create(_CALENDAR_POPUP_YEAR_GRID_STYLE_CLASS);
		}
		return CALENDAR_POPUP_YEAR_GRID_STYLE;
	}

	@Override
	public CssStyle getPopupMonthGridStyle() {
		if (CALENDAR_POPUP_MONTH_GRID_STYLE == null) {
			CALENDAR_POPUP_MONTH_GRID_STYLE = CssStyle
					.create(_CALENDAR_POPUP_MONTH_GRID_STYLE_CLASS);
		}
		return CALENDAR_POPUP_MONTH_GRID_STYLE;
	}

	/* Weeks Grid Styles */

	@Override
	public CssStyle getCalendarWeekGridStyle() {
		if (CALENDAR_WEEK_GRID_STYLE == null) {
			CALENDAR_WEEK_GRID_STYLE = CssStyle
					.create(_CALENDAR_WEEK_GRID_STYLE_CLASS);
		}
		return CALENDAR_WEEK_GRID_STYLE;
	}

	/* Days Grid styles */

	public CssStyle getCalendarGridCellStyle() {
		if (CALENDAR_GRID_CELL_STYLE == null) {
			CALENDAR_GRID_CELL_STYLE = CssStyle
					.create(_CALENDAR_GRID_CELL_STYLE_CLASS);
		}
		return CALENDAR_GRID_CELL_STYLE;
	}

	public CssStyle getDisabledGridCellStyle() {
		if (CALENDAR_NO_SELECTION_GRID_CELL_STYLE == null) {
			CALENDAR_NO_SELECTION_GRID_CELL_STYLE = CssStyle
					.create(_CALENDAR_DISABLED_SUFFIX);
		}
		return CALENDAR_NO_SELECTION_GRID_CELL_STYLE;
	}

	public CssStyle getSelectedGridCellStyle() {
		if (CALENDAR_SELECTED_CELL_STYLE == null) {
			CALENDAR_SELECTED_CELL_STYLE = getCalendarGridCellStyle()
					.addSuffix(_CALENDAR_SELECTED_SUFFIX);
		}
		return CALENDAR_SELECTED_CELL_STYLE;
	}

	/* Days Styles */

	@Override
	public CssStyle getCursorGridCellStyle() {
		if (CALENDAR_CURSOR_CELL_STYLE == null) {
			CALENDAR_CURSOR_CELL_STYLE = getCalendarGridCellStyle().addSuffix(
					_CALENDAR_CURSOR_SUFFIX);
		}
		return CALENDAR_CURSOR_CELL_STYLE;
	}

	public CssStyle getBriefDaysStyle() {
		if (CALENDAR_GRID_CELL_BRIEF_DAYS_STYLE == null) {
			CALENDAR_GRID_CELL_BRIEF_DAYS_STYLE = CssStyle
					.create(_CALENDAR_GRID_CELL_BRIEF_DAYS_STYLE_CLASS);
		}
		return CALENDAR_GRID_CELL_BRIEF_DAYS_STYLE;
	}

	public CssStyle getCurrentDayStyle() {
		if (CALENDAR_GRID_CELL_CURRENT_DAY_STYLE == null) {
			CALENDAR_GRID_CELL_CURRENT_DAY_STYLE = getCalendarGridCellStyle()
					.addSuffix(_CALENDAR_GRID_CELL_CURRENT_DAY_STYLE_CLASS);
		}
		return CALENDAR_GRID_CELL_CURRENT_DAY_STYLE;
	}

	public CssStyle getPreviousAndNextDayStyle() {
		if (CALENDAR_GRID_CELL_PREVIOUS_DAYS_STYLE == null) {
			CALENDAR_GRID_CELL_PREVIOUS_DAYS_STYLE = getCalendarGridCellStyle()
					.addSuffix(_CALENDAR_GRID_CELL_PREVIOUS_DAYS_STYLE_CLASS);
		}
		return CALENDAR_GRID_CELL_PREVIOUS_DAYS_STYLE;
	}

	/* Events Styles */

	public CssStyle getHolidaysDayStyle() {
		if (CALENDAR_GRID_CELL_HOLIDAYS_STYLE == null) {
			CALENDAR_GRID_CELL_HOLIDAYS_STYLE = getCalendarGridCellStyle()
					.addSuffix(_CALENDAR_GRID_CELL_HOLIDAYS_STYLE_CLASS);
		}
		return CALENDAR_GRID_CELL_HOLIDAYS_STYLE;
	}

	public CssStyle getSpecialDayStyle() {
		if (CALENDAR_GRID_CELL_SPECIAL_DAY_STYLE == null) {
			CALENDAR_GRID_CELL_SPECIAL_DAY_STYLE = getCalendarGridCellStyle()
					.addSuffix(_CALENDAR_GRID_CELL_SPECIAL_DAY_STYLE_CLASS);
		}
		return CALENDAR_GRID_CELL_SPECIAL_DAY_STYLE;
	}

	public CssStyle getBusyDayStyle() {
		if (CALENDAR_GRID_CELL_BUSY_DAY_STYLE == null) {
			CALENDAR_GRID_CELL_BUSY_DAY_STYLE = getCalendarGridCellStyle()
					.addSuffix(_CALENDAR_GRID_CELL_BUSY_DAY_STYLE_CLASS);
		}
		return CALENDAR_GRID_CELL_BUSY_DAY_STYLE;
	}

	public CssStyle getOthersDayStyle() {
		if (CALENDAR_GRID_CELL_OTHERS_STYLE == null) {
			CALENDAR_GRID_CELL_OTHERS_STYLE = getCalendarGridCellStyle()
					.addSuffix(_CALENDAR_GRID_CELL_OTHERS_STYLE_CLASS);
		}
		return CALENDAR_GRID_CELL_OTHERS_STYLE;
	}

	@Override
	public CssStyle[] getEventStyles() {
		CssStyle[] styles = new CssStyle[3];
		styles[0] = getHolidaysDayStyle();
		styles[1] = getSpecialDayStyle();
		styles[2] = getBusyDayStyle();
		return styles;
	}

	/* Years and Months Panel */

	/* For Short Renderer */
	public CssStyle getYearAndMonthPanelStyle() {
		if (CALENDAR_YEAR_AND_MONTH_PANEL_STYLE == null) {
			CALENDAR_YEAR_AND_MONTH_PANEL_STYLE = CssStyle
					.create(_CALENDAR_YEAR_AND_MONTH_PANEL_STYLE_CLASS);
		}
		return CALENDAR_YEAR_AND_MONTH_PANEL_STYLE;
	}

	public CssStyle getMediumYearAndMonthPanelStyle() {
		if (CALENDAR_MEDIUM_YEAR_AND_MONTH_PANEL_STYLE == null) {
			CALENDAR_MEDIUM_YEAR_AND_MONTH_PANEL_STYLE = CssStyle
					.create(_CALENDAR_MEDIUM_YEAR_AND_MONTH_PANEL_STYLE_CLASS);
		}
		return CALENDAR_MEDIUM_YEAR_AND_MONTH_PANEL_STYLE;
	}

	/* For Full renderer */
	@Override
	public CssStyle getFullYearPanelStyle() {
		if (CALENDAR_FULL_YEAR_PANEL_STYLE == null) {
			CALENDAR_FULL_YEAR_PANEL_STYLE = CssStyle
					.create(_CALENDAR_FULL_YEAR_PANEL_STYLE_CLASS);
		}
		return CALENDAR_FULL_YEAR_PANEL_STYLE;
	}

	public CssStyle getFullMonthPanelStyle() {
		if (CALENDAR_FULL_MONTH_PANEL_STYLE == null) {
			CALENDAR_FULL_MONTH_PANEL_STYLE = CssStyle
					.create(_CALENDAR_FULL_MONTH_PANEL_STYLE_CLASS);
		}
		return CALENDAR_FULL_MONTH_PANEL_STYLE;
	}

	/* Years, Months and weeks Label */

	public CssStyle getYearLabelStyle() {
		if (CALENDAR_YEAR_LABEL_STYLE == null) {
			CALENDAR_YEAR_LABEL_STYLE = CssStyle
					.create(_CALENDAR_YEAR_LABEL_STYLE_CLASS);
		}
		return CALENDAR_YEAR_LABEL_STYLE;
	}

	public CssStyle getMonthLabelStyle() {
		if (CALENDAR_MONTH_LABEL_STYLE == null) {
			CALENDAR_MONTH_LABEL_STYLE = CssStyle
					.create(_CALENDAR_MONTH_LABEL_STYLE_CLASS);
		}
		return CALENDAR_MONTH_LABEL_STYLE;
	}

	@Override
	public CssStyle getSelectedMonthesLabelStyle() {
		if (CALENDAR_SELECTED_MONTHES_LABEL_STYLE == null) {
			CALENDAR_SELECTED_MONTHES_LABEL_STYLE = CssStyle
					.create(_CALENDAR_SELECTED_MONTHES_LABEL_STYLE_CLASS);
		}
		return CALENDAR_SELECTED_MONTHES_LABEL_STYLE;
	}

	@Override
	public CssStyle getShortColumnStyle() {
		if (CALENDAR_SHORT_HEADER_COLUMN_STYLE == null) {
			CALENDAR_SHORT_HEADER_COLUMN_STYLE = CssStyle
					.create(_CALENDAR_SHORT_HEADER_COLUMN_STYLE_CLASS);
		}
		return CALENDAR_SHORT_HEADER_COLUMN_STYLE;
	}

	@Override
	public CssStyle getSingleLineColumnStyle() {
		if (CALENDAR_SINGLE_LINE_HEADER_COLUMN_STYLE == null) {
			CALENDAR_SINGLE_LINE_HEADER_COLUMN_STYLE = CssStyle
					.create(_CALENDAR_SINGLE_LINE_HEADER_COLUMN_STYLE_CLASS);
		}
		return CALENDAR_SINGLE_LINE_HEADER_COLUMN_STYLE;
	}

	public CssStyle getSelectedYearMonthLabelStyle() {
		if (CALENDAR_SELECTED_YEAR_MONTH_LABEL_STYLE == null) {
			CALENDAR_SELECTED_YEAR_MONTH_LABEL_STYLE = CssStyle
					.create(_CALENDAR_SELECTED_YEAR_MONTH_LABEL_STYLE_CLASS);
		}
		return CALENDAR_SELECTED_YEAR_MONTH_LABEL_STYLE;
	}

	@Override
	public CssStyle getMonthesStyle() {
		if (CALENDAR_MONTHES_LABEL_STYLE == null) {
			CALENDAR_MONTHES_LABEL_STYLE = CssStyle
					.create(_CALENDAR_MONTHES_LABEL_STYLE_CLASS);
		}
		return CALENDAR_MONTHES_LABEL_STYLE;
	}

	@Override
	public CssStyle getWeeksStyle() {
		if (CALENDAR_GRID_CELL_WEEKS_STYLE == null) {
			CALENDAR_GRID_CELL_WEEKS_STYLE = CssStyle
					.create(_CALENDAR_GRID_CELL_WEEKS_STYLE_CLASS);
		}
		return CALENDAR_GRID_CELL_WEEKS_STYLE;
	}

	@Override
	public CssStyle getSelectedWeeksStyle() {
		if (CALENDAR_SELECTED_GRID_CELL_WEEKS_STYLE == null) {
			CALENDAR_SELECTED_GRID_CELL_WEEKS_STYLE = getWeeksStyle()
					.addSuffix(_CALENDAR_SELECTED_SUFFIX);
		}
		return CALENDAR_SELECTED_GRID_CELL_WEEKS_STYLE;
	}

	/* Buttons Styles */

	public CssStyle getTodayButtonStyle() {
		if (CALENDAR_TODAY_BUTTON_STYLE == null) {
			CALENDAR_TODAY_BUTTON_STYLE = CssStyle
					.create(_CALENDAR_TODAY_BUTTON_STYLE_CLASS);
		}
		return CALENDAR_TODAY_BUTTON_STYLE;
	}

	public CssStyle getPreviousYearButtonStyle() {
		if (CALENDAR_PREVIOUS_YEAR_BUTTON_STYLE == null) {
			CALENDAR_PREVIOUS_YEAR_BUTTON_STYLE = CssStyle
					.create(_CALENDAR_PREVIOUS_YEAR_BUTTON_STYLE_CLASS);
		}
		return CALENDAR_PREVIOUS_YEAR_BUTTON_STYLE;
	}

	public CssStyle getNextYearButtonStyle() {
		if (CALENDAR_NEXT_YEAR_BUTTON_STYLE == null) {
			CALENDAR_NEXT_YEAR_BUTTON_STYLE = CssStyle
					.create(_CALENDAR_NEXT_YEAR_BUTTON_STYLE_CLASS);
		}
		return CALENDAR_NEXT_YEAR_BUTTON_STYLE;
	}

	public CssStyle getPreviousMonthButtonStyle() {
		if (CALENDAR_PREVIOUS_MONTH_BUTTON_STYLE == null) {
			CALENDAR_PREVIOUS_MONTH_BUTTON_STYLE = CssStyle
					.create(_CALENDAR_PREVIOUS_MONTH_BUTTON_STYLE_CLASS);
		}
		return CALENDAR_PREVIOUS_MONTH_BUTTON_STYLE;
	}

	public CssStyle getNextMonthButtonStyle() {
		if (CALENDAR_NEXT_MONTH_BUTTON_STYLE == null) {
			CALENDAR_NEXT_MONTH_BUTTON_STYLE = CssStyle
					.create(_CALENDAR_NEXT_MONTH_BUTTON_STYLE_CLASS);
		}
		return CALENDAR_NEXT_MONTH_BUTTON_STYLE;
	}

	public CssStyle getSemanticNavigationPanelStyle() {
		if (CALENDAR_SEMANTIC_NAVIGATION_PANEL_STYLE == null) {
			CALENDAR_SEMANTIC_NAVIGATION_PANEL_STYLE = CssStyle
					.create(_CALENDAR_SEMANTIC_NAVIGATION_PANEL_STYLE_CLASS);
		}
		return CALENDAR_SEMANTIC_NAVIGATION_PANEL_STYLE;
	}

	public CssStyle getPreviousButtonStyle() {
		if (CALENDAR_PREVIOUS_BUTTON_STYLE == null) {
			CALENDAR_PREVIOUS_BUTTON_STYLE = CssStyle
					.create(_CALENDAR_PREVIOUS_BUTTON_STYLE_CLASS);
		}
		return CALENDAR_PREVIOUS_BUTTON_STYLE;
	}

	public CssStyle getNextButtonStyle() {
		if (CALENDAR_NEXT_BUTTON_STYLE == null) {
			CALENDAR_NEXT_BUTTON_STYLE = CssStyle
					.create(_CALENDAR_NEXT_BUTTON_STYLE_CLASS);
		}
		return CALENDAR_NEXT_BUTTON_STYLE;
	}

	@Override
	public CssStyle getDisabledPreviousButtonStyle() {
		return getPreviousButtonStyle().addSuffix(_CALENDAR_DISABLED_SUFFIX);
	}

	@Override
	public CssStyle getDisabledNextButtonStyle() {
		return getNextButtonStyle().addSuffix(_CALENDAR_DISABLED_SUFFIX);
	}

	@Override
	public CssStyle getForbiddenStyle() {
		return CssStyle.create(_CALENDAR_FORBIDDEN_SUFFIX);
	}

	@Override
	public CssStyle getArrowButtonStyle() {
		if (CALENDAR_ARROW_BUTTON_STYLE == null) {
			CALENDAR_ARROW_BUTTON_STYLE = CssStyle
					.create(_CALENDAR_ARROW_BUTTON_STYLE_CLASS);
		}
		return CALENDAR_ARROW_BUTTON_STYLE;
	}

	@Override
	public CssStyle getOpenedArrowButtonStyle() {
		return getArrowButtonStyle().addSuffix(_CALENDAR_OPENED_SUFFIX);
	}

	/* Renderer */

	public IHeaderRenderer getSingleLineHeaderRenderer() {
		if (singleLineHeaderRenderer == null) {
			singleLineHeaderRenderer = new SingleLineCalendarHeaderRenderer();
		}
		return singleLineHeaderRenderer;
	}

	public IHeaderRenderer getPopupHeaderRenderer() {
		if (popupHeaderRenderer == null) {
			popupHeaderRenderer = new PopupCalendarHeaderRenderer();
		}
		return popupHeaderRenderer;
	}

	public IHeaderRenderer getShortHeaderRenderer() {
		if (shortHeaderRenderer == null) {
			shortHeaderRenderer = new ShortCalendarHeaderRenderer();
		}
		return shortHeaderRenderer;
	}

	public IHeaderRenderer getMediumHeaderRenderer() {
		if (mediumHeaderRenderer == null) {
			mediumHeaderRenderer = new MediumCalendarHeaderRenderer();
		}
		return mediumHeaderRenderer;
	}

	public IHeaderRenderer getFullHeaderRenderer() {
		if (fullHeaderRenderer == null) {
			fullHeaderRenderer = new FullCalendarHeaderRenderer();
		}
		return fullHeaderRenderer;
	}

	public ICalendarGridRenderer getDatesRenderer() {
		if (datesRenderer == null) {
			datesRenderer = new CalendarDatesRenderer();
		}
		return datesRenderer;
	}

	public ICalendarWeeksRenderer getWeekRenderer() {
		if (weekRenderer == null) {
			weekRenderer = new CalendarWeekColumnRenderer();
		}
		return weekRenderer;
	}

	public IFooterRenderer getFooterRenderer() {
		if (footerRenderer == null) {
			footerRenderer = new CalendarFooterRenderer();
		}
		return footerRenderer;
	}

	/**
	 * Returns a list of renderer depending on the RendererLevel passed
	 */

	@Override
	public Map<RendererType, IRenderer> getRenderers(RendererLevel rt) {
		Map<RendererType, IRenderer> renderers = new HashMap<RendererType, IRenderer>();
		if (rt == RendererLevel.SIMPLE) {
			renderers.put(RendererType.HEADER, getSingleLineHeaderRenderer());
			renderers.put(RendererType.DATES, getDatesRenderer());
			renderers.put(RendererType.WEEK, getWeekRenderer());
			renderers.put(RendererType.FOOTER, getFooterRenderer());
		} else if (rt == RendererLevel.POPUP) {
			renderers.put(RendererType.HEADER, getPopupHeaderRenderer());
			renderers.put(RendererType.DATES, getDatesRenderer());
			renderers.put(RendererType.WEEK, getWeekRenderer());
			renderers.put(RendererType.FOOTER, getFooterRenderer());
		} else if (rt == RendererLevel.SHORT) {
			renderers.put(RendererType.HEADER, getShortHeaderRenderer());
			renderers.put(RendererType.DATES, getDatesRenderer());
			renderers.put(RendererType.WEEK, getWeekRenderer());
			renderers.put(RendererType.FOOTER, getFooterRenderer());
		} else if (rt == RendererLevel.MEDIUM) {
			renderers.put(RendererType.HEADER, getMediumHeaderRenderer());
			renderers.put(RendererType.DATES, getDatesRenderer());
			renderers.put(RendererType.WEEK, getWeekRenderer());
			renderers.put(RendererType.FOOTER, getFooterRenderer());
		} else if (rt == RendererLevel.FULL) {
			renderers.put(RendererType.HEADER, getFullHeaderRenderer());
			renderers.put(RendererType.DATES, getDatesRenderer());
			renderers.put(RendererType.WEEK, getWeekRenderer());
			renderers.put(RendererType.FOOTER, getFooterRenderer());
		}
		return renderers;
	}
}